package com.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * Spring Context 工具类
 *
 * 该工具类用于方便地访问 Spring 的 ApplicationContext，以便在任何地方获取 Spring 管理的 Bean。
 * 它实现了 ApplicationContextAware 接口，通过 setApplicationContext 方法将 Spring 上下文注入到静态变量 applicationContext 中。
 *
 * @author team10
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {
	// 静态变量保存 Spring 上下文
	public static ApplicationContext applicationContext;

	/**
	 * 设置 Spring 应用上下文
	 *
	 * @param applicationContext Spring 应用上下文
	 * @throws BeansException 如果出现错误时抛出
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		SpringContextUtils.applicationContext = applicationContext;  // 将上下文赋值给静态变量
	}

	/**
	 * 根据 bean 名称获取 Spring 管理的 Bean
	 *
	 * @param name Bean 的名称
	 * @return 返回相应的 Bean 对象
	 */
	public static Object getBean(String name) {
		return applicationContext.getBean(name);  // 通过名称获取 Bean
	}

	/**
	 * 根据 bean 名称和类型获取 Spring 管理的 Bean
	 *
	 * @param name Bean 的名称
	 * @param requiredType 需要的类型
	 * @param <T> Bean 的类型
	 * @return 返回指定类型的 Bean 对象
	 */
	public static <T> T getBean(String name, Class<T> requiredType) {
		return applicationContext.getBean(name, requiredType);  // 通过名称和类型获取 Bean
	}

	/**
	 * 检查 Spring 上下文中是否包含指定的 Bean
	 *
	 * @param name Bean 的名称
	 * @return 如果上下文中包含该 Bean，返回 true，否则返回 false
	 */
	public static boolean containsBean(String name) {
		return applicationContext.containsBean(name);  // 检查是否包含指定的 Bean
	}

	/**
	 * 判断指定的 Bean 是否是单例的
	 *
	 * @param name Bean 的名称
	 * @return 如果该 Bean 是单例的，返回 true，否则返回 false
	 */
	public static boolean isSingleton(String name) {
		return applicationContext.isSingleton(name);  // 判断该 Bean 是否是单例
	}

	/**
	 * 获取指定 Bean 的类型
	 *
	 * @param name Bean 的名称
	 * @return 返回该 Bean 的类型
	 */
	public static Class<? extends Object> getType(String name) {
		return applicationContext.getType(name);  // 获取该 Bean 的类型
	}
}
